# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
import json
from redis import Redis
import hashlib
import pymongo
# scrapy自定义异常模块
from scrapy.exceptions import DropItem
from itemadapter import ItemAdapter


# class TxWorkPipeline:
#     def process_item(self, item, spider):
#         print(item)


# 自定义管道类
class TxWorkCheckPipeline:
    def open_spider(self, spider):
        if spider.name == 'tx_work_info':
            self.redis_client = Redis()

    def process_item(self, item, spider):
        if spider.name == 'tx_work_info':
            item_str = json.dumps(item)
            md5_hash = hashlib.md5()
            md5_hash.update(item_str.encode())
            hash_value = md5_hash.hexdigest()

            # 判断hash值是否存储在redis中
            if self.redis_client.get(f'tx_work_item_filter: {hash_value}'):
                print('数据重复...')
                raise DropItem  # 丢弃重复数据
            else:
                self.redis_client.set(f'tx_work_item_filter: {hash_value}', item_str)

            return item

    def close_spider(self, spider):
        if spider.name == 'tx_work_info':
            self.redis_client.close()


class TxWorkFilePipeline:
    # 在爬虫启动时创建一个文件对象
    def open_spider(self, spider):  # spider: 接收的是spider类的一个实例
        if spider.name == 'tx_work_info':
            self.file_obj = open('tx_work_info.txt', 'a', encoding='utf-8')

    def process_item(self, item, spider):
        """
        在当前方法中可以对item进行数据判断，如果不符合数据要求，一般有两种方式来处理:
            1. 扔掉
                如果数据不符合特定的条件或者质量标准，你可以直接从管道中排除它。
                这可以通过在管道的process_item方法中简单地返回None或抛出DropItem异常
                来实现。

            2. 修复
                在当前方法中编辑修复代码逻辑并使用return将修复的数据传递给下一个item

            注意:
                当前方法如果存在return item则将item数据传递给下一个item
                如果return不存在则将None传递给下一个item
        """

        # raise DropItem  丢掉不符合要求的数据

        if spider.name == 'tx_work_info':
            self.file_obj.write(json.dumps(item, ensure_ascii=False, indent=4) + '\n')
            print('数据写入文件成功:', item)
        return item

    def close_spider(self, spider):
        if spider.name == 'tx_work_info':
            self.file_obj.close()


class TxWorkMongoPipeline:
    # 在爬虫启动时创建一个数据库链接对象
    def open_spider(self, spider):  # spider: 接收的是spider类的一个实例
        if spider.name == 'tx_work_info':
            self.mongo_client = pymongo.MongoClient()
            self.collection = self.mongo_client['py_spider']['tx_work_info']

    def process_item(self, item, spider):
        if spider.name == 'tx_work_info':
            self.collection.insert_one(item)
            print('数据写入mongoDB成功:', item)
        return item

    def close_spider(self, spider):
        if spider.name == 'tx_work_info':
            self.mongo_client.close()
